
<div class="container">
	<a routerLink="/learn" class="btn btn-outline-dark" style="margin-top: 5px;">Back</a>
	<h2>Physics</h2>
	<p>In this tutorial we will experiment how physics work inside nunuStudio, physics are represented as objects in the editor, physics object dont have a visual representation they are just used for physics simulations.</p>
	<p>Physics in nunuStudio are powered by <a href="https://github.com/schteppe/cannon.js">cannon.js</a> developed by <a href="https://github.com/schteppe">schteppe</a>, for more information about the physics engine please consult the cannon.js <a href="http://www.cannonjs.org/">project page</a> and its <a href="http://schteppe.github.io/cannon.js/docs/">API documentation</a> page.</p>
	<p>The editor encapsulates the physics bodies in objects, these bodies are managed and updated on a scene basis, physics configuration is managed by scene.</p>

	<h3>Physics object</h3>

	<p>To add physics object select the desired physics object in the left toolbar and add it to the scene, after that add a mesh object as children of the newly created physics object to make it visible in the scene. Dont forget to add a ground object so that other physics object don't fall out of the screen.</p>
	<p>Physics object can be configured as dynamic, static or kinematic objects. Dynamic objects are updated dynamically and detect collisions, kinematic objects are updated only based on their speed, and static objects are not updated at all. Static objects behave likes walls or the floor.</p>

	<video src="assets/learn/basics/physics/video.mp4" style="width:60%; margin-left:20%" controls></video>

	<h3>Object positioning</h3>

	<p>There is a mode property that indicates how the physics coordinates are transformed from the physics world to the scene, the physics world does not consider the parental transformations applied to objects, <b>World</b> positioning is used to just copy world coordinates from physics to the object is fast and the coordinates will match the values stored in the physics body. Sometimes it is usefull to store physics object in the hierarchy, <b>Local</b> positioning can be used to adapt the physics world coordinates to match the scene, it has a small performance impact and the physics coordinates will not match the local transformation of the object.</p>
	<p>Bellow we have a comparison between world and local positioned physics objects inside a object hierarchy. As we can obvserve the <b>Local</b> positioned object behaves as we would expect.</p>

	<app-viewer fname="assets/learn/basics/physics/modes.nsp"></app-viewer>

	<h3>Physics object control</h3>

	<p>To interact with physics objects using scrips we need to get the physics body attached to that object. Then we can access the <i>body</i> property that exists in every physics object and change the forces, acceleration and velocity values to make it move around the scene.</p>
	<p>The following code gets an physics object body and using the keyboard WASD keys and the space bar we add velocity to that body forcing the cube to move around.</p>
	<pre><code class="hljs javascript">var body;

this.initialize = function()
{{'{'}}
	body = scene.getObjectByName("physics").body;
{{'}'}};

this.update = function()
{{'{'}}
	if(Keyboard.keyPressed(Keyboard.A))
	{{'{'}}
		body.velocity.x -= 0.2;
	{{'}'}}
	if(Keyboard.keyPressed(Keyboard.D))
	{{'{'}}
		body.velocity.x += 0.2;
	{{'}'}}
	if(Keyboard.keyPressed(Keyboard.W))
	{{'{'}}
		body.velocity.z -= 0.2;
	{{'}'}}
	if(Keyboard.keyPressed(Keyboard.S))
	{{'{'}}
		body.velocity.z += 0.2;
	{{'}'}}

	if(Keyboard.keyJustPressed(Keyboard.SPACEBAR))
	{{'{'}}
		body.velocity.y += 5;
	{{'}'}}
{{'}'}};</code></pre>

	<p>The code shown above can be seen running bellow for a physics cube, use the WASD keys to control the cube, and the spacebar to make the cube jump. Even when we dont specify rotation for the cube the physics engine automatically calculates it based on the friction beween the surface of the cube and floor. As we can observe the cube tumbles around the scene naturally.</p>

	<app-viewer fname="assets/learn/basics/physics/physics.nsp"></app-viewer>

	<p>It is also possible to detect collisions, contact points and explore the full state of the physics simulation. You can access the physics world from the scene object, and from there attach eventListeners to access the data after each simulation step for example.</p>

	<pre><code class="hljs javascript">var world = scene.world;
world.addEventListener("postStep", function(e)
{{'{'}}
	if(world.contacts.length > 0)
	{{'{'}}
		for(var i = 0; i < world.contacts.length; i++)
		{{'{'}}
			var contact = world.contacts[i];

			// Check collision between a and b
			if(contact.bi === a || contact.bj === b)
			{{'{'}}
				// ...
			{{'}'}}
		{{'}'}}
	{{'}'}}
{{'}'}}</code></pre>
</div>
